<?php
/**
 * @see Alinks_LinkBuilder_Interface
 */
require_once('Alinks/LinkBuilder/Interface.php');

/**
 * Class used for building links (i.e. anchor tags) in an
 * OO way. This is an important class for the factories, as
 * it's what needs to be returned by their parse() method.
 *
 * Example usage:
 *
 * $builder = new Alinks_LinkBuilder('http://google.com', 'Google');
 * echo $builder->getHtml();
 * // Outputs: <a href="http://google.com">Google</a>
 *
 * $builder = new Alinks_LinkBuilder();
 * $builder->setUri('http://google.com');
 * $builder->setText('Google');
 * $builder->addClass('alinks');
 * echo $builder->getHtml();
 * // Outputs: <a href="http://google.com" class="alinks">Google</a>
 *
 * $builder = new Alinks_LinkBuilder('http://google.com', 'Google');
 * $builder->addClass('alinks');
 * $builder->addClass('default');
 * $builder->addPreHtml('<div>');
 * $builder->addPostHtml('</div>');
 * $builder->setInnerHtml('target="_blank"');
 * echo $builder->getHtml();
 * // Outputs: <div><a href="http://google.com" target="_blank" class="alinks default">Google</a></div>
 *
 * $builder = new Alinks_LinkBuilder('http://google.com', 'Google');
 * $builder->setId('link1');
 * $builder->addArg('onclick', 'alert(this.id)');
 * echo $builder->getHtml();
 * // Outputs: <a href="http://google.com" id="link1" onclick="alert(this.id)">Google</a>
 *
 * Copyright (C) 2008  Sean Hickey
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author Sean Hickey <sean@headzoo.com>
 * @version $Id: LinkBuilder.php 381 2008-07-03 05:29:05Z sean $
 * @package Alinks_LinkBuilder
 */
class Alinks_LinkBuilder implements Alinks_LinkBuilder_Interface
{
	/**
	 * The data for this link
	 *
	 * @var array
	 */
	protected $_data = array();
	
	/**
	 * Constructor
	 *
	 * @param string $uri The link URI
	 * @param string $text The link inner text
	 */
	public function __construct($uri = null, $text = null)
	{
		$this->reset();
		$this->setUri($uri);
		$this->setText($text);
	}
	
	/**
	 * Returns the link URI
	 *
	 * @return string
	 */
	public function getUri()
	{
		return $this->_data['uri'];
	}
	
	/**
	 * Returns the link inner text
	 *
	 * @return string
	 */
	public function getText()
	{
		return $this->_data['text'];
	}
	
	/**
	 * Returns the classes attached to the link
	 *
	 * @return array
	 */
	public function getClasses()
	{
		return $this->_data['classes'];
	}
	
	/**
	 * Returns the link ID
	 *
	 * @return string
	 */
	public function getId()
	{
		return $this->_data['id'];
	}
	
	/**
	 * Returns the link pre HTML strings
	 *
	 * @return array
	 */
	public function getPreHtml()
	{
		return $this->_data['pre_html'];
	}
	
	/**
	 * Returns the link post HTML strings
	 *
	 * @return array
	 */
	public function getPostHtml()
	{
		return $this->_data['post_html'];
	}
	
	/**
	 * Returns the link args
	 *
	 * Returns the link args. If $arg is provided, then the value for
	 * that arg is returned instead of all the args.
	 *
	 * @param string $arg Argument key
	 * @return array|string
	 */
	public function getArgs($arg = null)
	{
		if (null !== $arg) {
			if (!isset($this->_data['args'][$arg])) {
				throw new Exception("Argument '$arg' not set");
			}
			return $this->_data['args'][$arg];
		}
		return $this->_data['args'];
	}
	
	/**
	 * Returns the inner HTML
	 *
	 * The inner HTML is any arbitrary HTML that should go inside
	 * the anchor tag.
	 *
	 * @return string
	 */
	public function getInnerHtml()
	{
		return $this->_data['inner_html'];
	}
	
	/**
	 * Sets the link URI
	 *
	 * @param string $uri The link URI
	 * @return Alinks_LinkBuilder
	 */
	public function setUri($uri)
	{
		$this->_data['uri'] = $uri;
		return $this;
	}
	
	/**
	 * Sets the link inner text
	 *
	 * @param string $text The inner text
	 * @return Alinks_LinkBuilder
	 */
	public function setText($text)
	{
		$this->_data['text'] = $text;
		return $this;
	}
	
	/**
	 * Sets the link CSS classes
	 *
	 * @param array $classes Array of CSS classes
	 * @return Alinks_LinkBuilder
	 */
	public function setClasses(array $classes)
	{
		$this->_data['classes'] = $classes;
		return $this;
	}
	
	/**
	 * Adds a CSS class to the link
	 *
	 * @param string $class The class name
	 * @return Alinks_LinkBuilder
	 */
	public function addClass($class)
	{
		$this->_data['classes'][] = $class;
		return $this;
	}
	
	/**
	 * Sets the link ID
	 *
	 * @param string $id The link ID
	 * @return Alinks_LinkBuilder
	 */
	public function setId($id)
	{
		$this->_data['id'] = $id;
		return $this;
	}
	
	/**
	 * Sets the link pre HTML strings
	 *
	 * The pre HTML is any HTML that should come before the anchor tag
	 * HTML.
	 *
	 * @param array $pre_html The pre HTML strings
	 * @return Alinks_LinkBuilder
	 */
	public function setPreHtml(array $pre_html)
	{
		$this->_data['pre_html'] = $pre_html;
		return $this;
	}
	
	/**
	 * Adds a pre HTML string to the link
	 *
	 * The pre HTML is any HTML that should come before the anchor tag
	 * HTML.
	 *
	 * @param string $pre_html The pre HTML string
	 * @return Alinks_LinkBuilder
	 */
	public function addPreHtml($pre_html)
	{
		$this->_data['pre_html'][] = $pre_html;
		return $this;
	}
	
	/**
	 * Sets the link post HTML strings
	 *
	 * The post HTML is any HTML that comes after the anchor tag
	 * HTML.
	 *
	 * @param array $post_html The post HTML strings
	 * @return Alinks_LinkBuilder
	 */
	public function setPostHtml(array $post_html)
	{
		$this->_data['post_html'] = $post_html;
		return $this;
	}
	
	/**
	 * Adds a post HTML string
	 *
	 * The post HTML is any HTML that comes after the anchor tag
	 * HTML.
	 *
	 * @param string $post_html The post HTML string
	 * @return Alinks_LinkBuilder
	 */
	public function addPostHtml($post_html)
	{
		$this->_data['post_html'][] = $post_html;
		return $this;
	}
	
	/**
	 * Sets the link arguments
	 *
	 * @param array $args The arguments
	 * @param Alinks_LinkBuilder
	 */
	public function setArgs(array $args)
	{
		$this->_data['args'] = $args;
		return $this;
	}
	
	/**
	 * Adds an argument to the link
	 *
	 * @param string $key The argument key
	 * @param string $value The argument value
	 * @return Alinks_LinkBuilder
	 */
	public function addArg($key, $value)
	{
		$this->_data['args'][$key] = $value;
		return $this;
	}
	
	/**
	 * Sets the inner HTML
	 *
	 * The inner HTML is any arbitrary HTML that should go inside
	 * the anchor tag.
	 *
	 * @param string $html The inner HTML
	 * @return Alinks_LinkBuilder
	 */
	public function setInnerHtml($html)
	{
		$this->_data['inner_html'] = $html;
		return $this;
	}
	
	/**
	 * Returns the link HTML
	 *
	 * @return string
	 */
	public function getHtml()
	{
		$html = join('', $this->_data['pre_html']);
		$html .= '<a href="' . $this->_data['uri'] . '"';
		if (null !== $this->_data['id']) {
			$html .= ' id="' . $this->_data['id'] . '"';
		}
		if (!empty($this->_data['classes'])) {
			$html .= ' class="' . join(' ', $this->_data['classes']) . '"';
		}
		if (!empty($this->_data['args'])) {
			$html .= ' ' . $this->_getArgsToString();
		}
		if (null !== $this->_data['inner_html']) {
			$html .= ' ' . $this->_data['inner_html'];
		}
		$html .= '>' . $this->_data['text'] . '</a>';
		$html .= join('', $this->_data['post_html']);
		return $html;
	}
	
	/**
	 * Returns the link HTML
	 *
	 * @return string
	 */
	public function __toString()
	{
		return $this->getHtml();
	}
	
	/**
	 * Returns the link values as an array
	 *
	 * @return array
	 */
	public function toArray()
	{
		return $this->_data;
	}
	
	/**
	 * Resets the builder to it's default values
	 *
	 * @return bool
	 */
	public function reset()
	{
		$this->_data = array(
			'uri' 			=> null,
			'text' 			=> null,
			'classes' 		=> array(),
			'id' 			=> null,
			'pre_html' 		=> array(),
			'post_html' 	=> array(),
			'args' 			=> array(),
			'inner_html' 	=> null
		);
	}
	
	/**
	 * Returns the link args as a string
	 *
	 * @return string
	 */
	protected function _getArgsToString()
	{
		$args = array();
		foreach($this->_data['args'] as $key => $value) {
			$args[] = $key . '="' . htmlentities($value) . '"';
		}
		
		return join(' ', $args);
	}
}